package sanshui.system.trade.factory.trade.riskCtr.impl;

import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import sanshui.system.trade.db.entity.TradeTargetCode;
import sanshui.system.trade.factory.trade.TradeSystemContext;
import sanshui.system.trade.factory.trade.riskCtr.AbstractRiskStrategy;
import sanshui.system.trade.factory.trade.riskCtr.RiskCtrCode;
import sanshui.system.trade.factory.trade.strategy.StrategyCallType;
import sanshui.system.trade.factory.trade.strategy.StrategyResult;
import sanshui.system.trade.model.RiskModel;
import sanshui.system.trade.model.WenCaiRiskModel;
import sanshui.system.trade.service.ITradeTargetCodeService;
import sanshui.system.trade.util.CommonTimeUtil;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class WenCaiRiskCtrl extends AbstractRiskStrategy {
    @Resource
    ITradeTargetCodeService targetCodeService;

    @Override
    public RiskCtrCode getRiskName() {
        return RiskCtrCode.WEN_CAI_RISK;
    }
    @Override
    public String getDesc() {
        return RiskCtrCode.WEN_CAI_RISK.getMessage();
    }

    @Override
    public List<StrategyResult> exec(TradeSystemContext tradeSystemContext, List<StrategyResult> strategyResults) {
        List<StrategyResult> riskResult = new ArrayList<>();

        Map<String, StrategyResult> buyMap = new HashMap<>();
        Map<String, StrategyResult> sellMap = new HashMap<>();

        for (StrategyResult strategyResult : strategyResults) {
            if (StrategyCallType.SELL.compareTo(strategyResult.getStrategyCallType()) == 0) {
                sellMap.put(strategyResult.getCode(), strategyResult);
            }
            if (StrategyCallType.BUY.compareTo(strategyResult.getStrategyCallType()) == 0){
                buyMap.put(strategyResult.getCode(), strategyResult);
            }
        }

        List<RiskModel> riskModelList = tradeSystemContext.getRiskModelList();
        List<WenCaiRiskModel> wenCaiRiskModels = BeanUtil.copyToList(riskModelList, WenCaiRiskModel.class);

        /**
         * wencai风控只会给买入
         * 具体买卖需要看持有时间等风控信息进行换仓
         *  当前买入标的是否已经持有
         *      持有了，查看风控指标是否继续持有
         *      没有持有，是否满足风控指标(持有数量有关)
         * */
        // 当前worker持有
        List<TradeTargetCode> targetCodesByWorkerId = targetCodeService.findTargetCodesByWorkerId(tradeSystemContext.getWorkerId());
        WenCaiRiskModel riskModel = null;
        List<TradeTargetCode> holdTargetModels = new ArrayList<>();
        List<String> noHoldTargetModels = new ArrayList<>();
        for (String tsCode : buyMap.keySet()) {
            TradeTargetCode holdTargetModel = targetCodeService.findTargetCodeInList(tsCode, targetCodesByWorkerId);
            if (null != holdTargetModel){
                holdTargetModels.add(holdTargetModel);
            } else {
                noHoldTargetModels.add(tsCode);
            }
        }

        buyMap = this.holdTargetIfBuy(buyMap, noHoldTargetModels, 4);


        sellMap = this.holdTargetIfSell(wenCaiRiskModels, holdTargetModels, tradeSystemContext);



        if (riskModel == null){
            // 没有持有

        }

        Map<String, StrategyResult> finalSellMap = sellMap;
        sellMap.forEach((code, strategyResult) ->{
            this.sell(code, strategyResult, finalSellMap, tradeSystemContext);
            riskResult.add(strategyResult);
        });

        Map<String, StrategyResult> finalBuyMap = buyMap;
        buyMap.forEach((code, strategyResult) ->{
            this.buy(code, strategyResult, finalBuyMap, tradeSystemContext);
            riskResult.add(strategyResult);
        });
        return riskResult;
    }

    @Override
    protected void sell(String code, StrategyResult strategyResult, Map<String, StrategyResult> sellMap, TradeSystemContext tradeSystemContext) {
        super.sell(code, strategyResult, sellMap, tradeSystemContext);
    }

    @Override
    protected void buy(String code, StrategyResult strategyResult, Map<String, StrategyResult> buyMap, TradeSystemContext tradeSystemContext) {


        // 查库，上次换仓时间，只有达到换仓时间才换股


//        if (null != targetCode){
//            // 持有了
//
//        } else {
//            // 当前没有持有，需要判断是否可以换仓了
//            strategyResult.setCode(stockInfoModel.getCodeWencai());
//            strategyResult.setName(stockInfoModel.getCodeNameWencai());
//            strategyResult.setPrice(Float.valueOf(Float.parseFloat(stockInfoModel.getPriceWencai()) * 100).longValue());
//            strategyResult.setStrategyCallType(StrategyCallType.BUY);
//        }
        super.buy(code, strategyResult, buyMap, tradeSystemContext);
    }


    /**
     * 判断当前持有标的是否该卖出
     * */
    Map<String, StrategyResult> holdTargetIfSell(List<WenCaiRiskModel> wenCaiRiskModels, List<TradeTargetCode> holdTargetModels, TradeSystemContext tradeSystemContext){
        Map<String, StrategyResult> sellMap = new HashMap<>();
        for (TradeTargetCode holdTargetModel : holdTargetModels) {
            for (WenCaiRiskModel riskModel : wenCaiRiskModels) {
                if (holdTargetModel.getTsCode().equalsIgnoreCase(riskModel.getTsCode())){
                    int maxHoldDay = riskModel.getMaxHoldDay();
                    String addTime = holdTargetModel.getAddTime();
                    int nowWinRate = riskModel.getNowWinRate();

                    if (CommonTimeUtil.compare(CommonTimeUtil.getTimestamp(addTime), LocalDateTime.now(), maxHoldDay, ChronoUnit.DAYS)){
                        // 超过了持有时间
                        // 判断收益是否满足
                        if (nowWinRate > riskModel.getMustHoldRateH() &&
                                (riskModel.getMaxWinRate() - nowWinRate) * 100 / nowWinRate < riskModel.getHighDownRateH() ){
                            // 当前收益大于必须持的收益 且 当前回落收益小于最大回落
                            // 继续持有
                            continue;
                        }
                    } else {
                        if (nowWinRate < riskModel.getLowRateH()){
                            // 当前收益小于必须持的收益
                            // 卖出

                        }
                    }
                    continue;
                }
            }
            log.error("当前标的没有对应的风控模型, tsCode:{}", holdTargetModel.getTsCode());
        }
        return null;
    }

    /**
     * 判断满足策略标的是否该买入（换仓）
     * @param maxHoldNum: 最大持有数量
     * */
    Map<String, StrategyResult> holdTargetIfBuy(Map<String, StrategyResult> buyMap, List<String> noHoldTargetModels, int maxHoldNum){
//        for (TradeTargetCode holdTargetModel : holdTargetModels) {
//            for (WenCaiRiskModel riskModel : wenCaiRiskModels) {
//                if (holdTargetModel.getTsCode().equalsIgnoreCase(riskModel.getTsCode())) {
//
//                }
//            }
//        }

        return buyMap;
    }
}
